# !/usr/bin/env python3
# -*- coding: utf-8 -*-


import xml.etree.ElementTree as EleTree
from util.lib import pretty_xml


def _init_aux_tbl_xml(test_aux_set, test_aux_tbl_xml):
    root = EleTree.Element('test_aux_tbl')
    for entry in test_aux_set:
        node_ele = EleTree.SubElement(root, 'node')
        node_id = EleTree.SubElement(node_ele, 'node_id')
        node_id.text = str(entry['node_id'])
        entry_ele = EleTree.SubElement(node_ele, 'entry')

        reserve_id = 1
        for port_id in range(4):
            reserve_name = 'reserved%d' % reserve_id
            reserved_ele = EleTree.SubElement(entry_ele, reserve_name)
            reserved_ele.text = '0'
            reserve_id = reserve_id + 1
            name = 'rx_flowid_p%d' % port_id
            if int(entry['flow_rx_port']) == port_id:
                rx_flowid_pN_ele = EleTree.SubElement(entry_ele, name)
                rx_flowid_pN_ele.text = str(entry['flow_id'])
            else:
                rx_flowid_pN_ele = EleTree.SubElement(entry_ele, name)
                rx_flowid_pN_ele.text = '0'
        for port_id in range(4):
            reserve_name = 'reserved%d' % reserve_id
            reserved_ele = EleTree.SubElement(entry_ele, reserve_name)
            reserved_ele.text = '0'
            reserve_id = reserve_id + 1
            name = 'tx_flowid_p%d' % port_id
            if int(entry['flow_tx_port']) == port_id:
                tx_flowid_pN_ele = EleTree.SubElement(entry_ele, name)
                tx_flowid_pN_ele.text = str(entry['flow_id'])
            else:
                tx_flowid_pN_ele = EleTree.SubElement(entry_ele, name)
                tx_flowid_pN_ele.text = '0'

        reserve_name = 'reserved%d' % reserve_id
        reserved_ele = EleTree.SubElement(entry_ele, reserve_name)
        reserved_ele.text = '0'
        reserve_id = reserve_id + 1
        pto_select_ele = EleTree.SubElement(entry_ele, 'pto_select')
        pto_select_ele.text = str(entry['pto_select'])
        tx_pulse_ele = EleTree.SubElement(entry_ele, 'tx_pulse')
        tx_pulse_ele.text = str(entry['flow_tx_port'])
        rx_pulse_ele = EleTree.SubElement(entry_ele, 'rx_pulse')
        rx_pulse_ele.text = str(entry['flow_rx_port'])

        reserve_name = 'reserved%d' % reserve_id
        reserved_ele = EleTree.SubElement(entry_ele, reserve_name)
        reserved_ele.text = '0'
        reserve_id = reserve_id + 1
        dmac = str(entry['dmac']).split(':')
        dmac_1 = '0x'
        dmac_2 = '0x'
        for item in dmac[:2]:
            dmac_1 += item
        for item in dmac[2:]:
            dmac_2 += item
        dmac_1_ele = EleTree.SubElement(entry_ele, 'dmac_1')
        dmac_1_ele.text = dmac_1
        dmac_2_ele = EleTree.SubElement(entry_ele, 'dmac_2')
        dmac_2_ele.text = dmac_2

        reserve_name = 'reserved%d' % reserve_id
        reserved_ele = EleTree.SubElement(entry_ele, reserve_name)
        reserved_ele.text = '0'
        reserve_id = reserve_id + 1
        mirror_mode = EleTree.SubElement(entry_ele, 'mirror_mode')
        mirror_mode.text = str(entry['mirror_mode'])

        for id in range(16):
            reserve_name = 'reserved%d' % reserve_id
            reserved_ele = EleTree.SubElement(entry_ele, reserve_name)
            reserved_ele.text = '0'
            reserve_id = reserve_id + 1
            name = 'flow_id_%d' % id
            valid_id = id
            valid_name = 'valid%d' % valid_id
            if id < len(entry['flow_id_set']):
                valid_id_ele = EleTree.SubElement(entry_ele, valid_name)
                valid_id_ele.text = '1'
                flow_id_N_ele = EleTree.SubElement(entry_ele, name)
                flow_id_N_ele.text = str(entry['flow_id_set'][id]['flow_id'])
            else:
                valid_id_ele = EleTree.SubElement(entry_ele, valid_name)
                valid_id_ele.text = '0'
                flow_id_N_ele = EleTree.SubElement(entry_ele, name)
                flow_id_N_ele.text = '0'

    tree = EleTree.ElementTree(root)
    pretty_xml(root, '\t', '\n')
    tree.write(test_aux_tbl_xml,
               encoding='utf-8',
               xml_declaration=True)

    return


def assemble_aux_tbl(test_aux_xml, test_aux_tbl_xml):
    test_aux_set = []

    root = EleTree.parse(test_aux_xml)
    node_ele_set = root.findall('node')
    for node_ele in node_ele_set:
        node = {}
        node_id = node_ele.findtext('node_id')
        node_id = int(node_id, 16)
        node.update({'node_id': node_id})
        pulse_ele = node_ele.find('pulse')
        flow_id = pulse_ele.findtext('flow_id')
        flow_rx_port = pulse_ele.findtext('flow_rx_port')
        flow_tx_port = pulse_ele.findtext('flow_tx_port')
        pto_select = pulse_ele.findtext('pto_select')
        node.update({'flow_id': flow_id,
                     'flow_rx_port': flow_rx_port,
                     'flow_tx_port': flow_tx_port,
                     'pto_select': pto_select})
        mirror_pkt_ele = node_ele.find('mirror_pkt')
        dmac = mirror_pkt_ele.findtext('dmac')
        mirror_mode = mirror_pkt_ele.findtext('mirror_mode')
        node.update({'dmac': dmac,
                     'mirror_mode': mirror_mode})
        flow_id_set = []
        flow_id_table = mirror_pkt_ele.find('flow_id_table')
        flow_id_table_set = flow_id_table.findall('entry')
        for flow_id_tble in flow_id_table_set:
            flow_id = flow_id_tble.findtext('flow_id')
            flow_id_set.append({'flow_id': flow_id})
        node.update({'flow_id_set': flow_id_set})
        test_aux_set.append(node)

    _init_aux_tbl_xml(test_aux_set, test_aux_tbl_xml)

    return


def main():
    test_aux_xml = '../input/test_aux.xml'
    test_aux_tbl_xml = '../output/tbl/test_aux_tbl.xml'

    assemble_aux_tbl(test_aux_xml, test_aux_tbl_xml)
    return


if __name__ == '__main__':
    main()


